package com.magnificent.panda.correlation;

import com.magnificent.panda.model.entity.FlowEvent;

/**
 * User: Babanin
 * Date: 03.10.2009
 * Time: 15:43:01
 */
public class ProhorovCorrelationFunction implements IntervalCorrelationFunction {

    private int minCount;    //  minimum of first and second flow length
    private double deltaTau;    //  interval of discretization
    private int countOfSecondStream;  //  length of second stream
    private int countOfCorrelationFunction;  //  length of correlation array

    private FlowEvent firstStream[];   //  first flow
    private FlowEvent secondStream[];  //  second flow
    private double correlationFunctionResult[];  //  result of correlation function

    public double[] calculateCorrelation(FlowEvent firstStream[], FlowEvent secondStream[], int countOfCorrelationFunction, double deltaTau) {
        // Initialize
        this.deltaTau = deltaTau;
        this.firstStream = firstStream;
        this.secondStream = secondStream;

        if (countOfCorrelationFunction == -1) {
            try {
                countOfCorrelationFunction = (int)
                        Math.abs(
                                Math.floor(
                                        (secondStream[secondStream.length - 1].getValue() - firstStream[0].getValue()) / deltaTau + 0.5
                                ) + 1
                        );
            } catch (ArrayIndexOutOfBoundsException e) {
                e.printStackTrace();
            }
        }

        countOfSecondStream = secondStream.length;
        minCount = Math.min(firstStream.length, secondStream.length);

        correlationFunctionResult = new double[countOfCorrelationFunction];

        // Count
        for (int j = 0; j < countOfCorrelationFunction; j++) {

            int sum = 0;
            for (int i = 1; i <= minCount; i++) {
                for (int s = 0; s <= (countOfSecondStream - i); s++) {
                    sum += calcStateIndicator(j, i, s);
                }
            }

            correlationFunctionResult[j] = (1.0 / minCount) * sum;
        }


        return correlationFunctionResult;
    }

    public int calcStateIndicator(int j, int i, int s) {
        try {
            int stateIndicator = (int) Math.floor((secondStream[i + s - 1].getValue() - firstStream[i - 1].getValue()) / deltaTau + 0.5);

            if (stateIndicator == j) {
                return 1;
            } else {
                return 0;
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
            return 0;
        }
    }

    public double[] calculateCorrelation(FlowEvent[] mainStream, FlowEvent[][] secondaryStream, int correlationSize, double deltaTau, boolean useConnectivity) {
        return null;
    }

    public boolean isMultiFlowsSupported() {
        return false;
    }

    public int calcStateIndicator(int j, int i, int k, int m, boolean useConnectivity) {
        return 0;
    }

    @Override
    public String toString() {
        return "ИКФ №1";
    }
}
  /* converted to utf8 */